package com.zz.framework.core.utils

import android.app.Activity
import android.app.Application
import android.util.Log
import androidx.collection.ArrayMap
import com.zz.framework.core.base.BaseActivity
import kotlin.concurrent.Volatile
import kotlin.system.exitProcess

/**
 * 应用程序Activity管理类，用于Activity管理和应用程序退出
 */
class ActivityStackManager private constructor() {
    private val mActivitySet = ArrayMap<String, BaseActivity>()
    /**
     * 当前 Activity 对象标记
     */
    private var mCurrentTag: String? = null
    val application: Application = AppGlobals.getApplication()
    val topActivity: BaseActivity?
        /**
         * 获取栈顶的 Activity
         */
        get() = mActivitySet[mCurrentTag]

    /**
     * 销毁所有的 Activity
     */
    fun finishAllActivities() {
        finishAllActivities((null as Class<out BaseActivity?>?)!!)
    }

    fun finishActivitiesExcludeMain() {
        getMainActivityClass()?.let {
            finishAllActivities(it)
        }?: finishAllActivities()
    }


    val bottomActivity: BaseActivity?
        /**
         * 获取栈底部的Activity
         */
        get() {
            Log.d(TAG, "getBottomActivity mActivitySet.size() = " + mActivitySet.size)
            return if (mActivitySet.isNotEmpty()) {
                mActivitySet[mActivitySet.keyAt(0)]
            } else {
                topActivity
            }
        }

    fun findFirstActivity(clazz: Class<out Activity>): BaseActivity? {
        for (activity in mActivitySet.values) {
            if (activity.javaClass == clazz) {
                return activity
            }
        }
        return null
    }

    /**
     * 销毁所有的 Activity，除这些 Class 之外的 Activity
     */
    fun finishAllActivities(vararg classArray: Class<out Activity?>) {
        val keys = mActivitySet.keys
        for (key in keys) {
            val activity = mActivitySet[key]
            if (activity != null && !activity.isFinishing) {
                var whiteClazz = false
                if (classArray != null) {
                    for (clazz in classArray) {
                        if (activity.javaClass == clazz) {
                            whiteClazz = true
                        }
                    }
                }
                // 如果不是白名单上面的 Activity 就销毁掉
                if (!whiteClazz) {
                    activity.finish()
                    mActivitySet.remove(key)
                }
            }
        }
    }

    /** 退出应用 */
    fun exitApp() {
        finishAllActivities()
        android.os.Process.killProcess(android.os.Process.myPid())
        exitProcess(0)
    }

    /**
     * Activity 同名方法回调
     */
    fun onCreated(activity: BaseActivity) {
        mCurrentTag = getObjectTag(activity)
        mActivitySet[getObjectTag(activity)] = activity
    }

    /**
     * Activity 同名方法回调
     */
    fun onDestroyed(activity: BaseActivity) {
        mActivitySet.remove(getObjectTag(activity))
        // 如果当前的 Activity 是最后一个的话
        if (getObjectTag(activity) == mCurrentTag) {
            // 清除当前标记
            mCurrentTag = null
        }
        if (mActivitySet.isNotEmpty()) {
            mCurrentTag = mActivitySet.keyAt(mActivitySet.size - 1)
        }
    }

    companion object {
        private const val TAG = "ActivityStackManager"
        @Volatile
        private var sInstance: ActivityStackManager? = null
        val instance: ActivityStackManager
            get() {
                // 加入双重校验锁
                if (sInstance == null) {
                    synchronized(ActivityStackManager::class.java) {
                        if (sInstance == null) {
                            sInstance = ActivityStackManager()
                        }
                    }
                }
                return sInstance!!
            }

        /**
         * 获取一个对象的独立无二的标记
         */
        private fun getObjectTag(obj: Any): String {
            // 对象所在的包名 + 对象的内存地址
            return obj.javaClass.name + Integer.toHexString(obj.hashCode())
        }
    }


    private var mActivityClass: Class<out Activity>? = null
    fun setMainActivity(mActivity: Class<out Activity>?) {
        mActivityClass = mActivity
    }
    fun getMainActivityClass(): Class<out Activity>? {
        return mActivityClass
    }

}
